import path, { resolve } from "path";
import { defineConfig } from "vite";

import react from "@vitejs/plugin-react";
import { visualizer } from "rollup-plugin-visualizer";
import { autoComplete, Plugin as importToCDN } from "vite-plugin-cdn-import";
import { VitePWA } from "vite-plugin-pwa";
import requireTransform from "vite-plugin-require-transform";
import packageJson from "./package.json";
import webManifest from "./public/manifest.json";
const pathResolve = (pathUrl) => path.join(__dirname, pathUrl);
const buildTime = `${new Date().getTime()}`;

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    // 代码分析插件
    visualizer({
      emitFile: true, // 打包后的分析文件会出现在打包好的文件包下
      filename: "stats.html", // 分析图生成的文件名
      open: true, // 如果存在本地服务端口，将在打包后自动展示
      gzipSize: true, // 分析图生成的文件名
      brotliSize: true, // 收集 brotli 大小并将其显示
    }),
    requireTransform({}),
    importToCDN({
      modules: [autoComplete("react"), autoComplete("react-dom")],
    }),
    VitePWA({
      manifest: webManifest,
      injectRegister: null,
      filename: "pwa.js",
      devOptions: {
        // 如果想在`vite dev`命令下调试PWA, 必须启用它
        enabled: true,
        // Vite在dev模式下会使用浏览器原生的ESModule，将type设置为`"module"`与原先的保持一致
        type: "module",
      },
    }),
  ],
  // 缩写
  resolve: {
    alias: {
      "@": pathResolve("src"),
    },
  },
  // 定义变量
  define: {
    "process.env": process.env,
    "process.env.BUILD_TIME": JSON.stringify(`${new Date().toLocaleString()}`),
    "process.env.PACKAGE_VERSION": JSON.stringify(packageJson.version),
  },
  // 服务器相关
  server: {
    // 配置可以IP访问
    host: "0.0.0.0",
    // 本地服务的端口号
    port: 2800,
    // 启动时，自动在浏览器中打开应用程序。当该值为字符串时，它将被用作 URL 的路径名
    open: true, // 是否自动打开浏览器
    // 代理配置
    proxy: {
      "/service": {
        // target: 'http://api.bbwwj.net',
        // target: 'https://sitapi.wjdemo.com',
        target: "https://m.wjdemo.com",
        // target: 'https://api.wjdemo.com',
        // target: 'http://192.168.2.32:9001',
        // target: 'http://192.168.2.5:9005',
        changeOrigin: true,
      },
      "/api": {
        target: "https://api.wjdemo.com",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ""), // rewrite path
      },
      // 代理 websockets 或 socket.io 写法：ws://localhost:5173/socket.io -> ws://localhost:5174/socket.io
      // '/webSocket': {
      //   // target: 'ws://192.168.2.105:9001', // 要代理到的 WebSocket 地址
      //   target: 'wss://m.wjdemo.com', // 要代理到的 WebSocket 地址
      //   ws: true,
      //   changeOrigin: true,
      //   pathRewrite: {
      //     '^/webSocket': '',
      //   },
      // },
    },
    // 本地服务的响应头设置
    headers: {
      // 允许跨域
      "Access-Control-Allow-Origin": "*",
    },
  },
  // 构建相关
  build: {
    outDir: "./build",
    emptyOutDir: true, // 打包时先清空上一次构建生成的目录
    minify: "terser", // boolean | 'terser' | 'esbuild', // 默认 esbuild 小项目更快专注压缩，terser功能更多，适合大项目
    sourcemap: false, // 构建后是否生成 source map 文件
    // target: 'esnext',
    target: "es2015",
    // 以下如果是terser才需要
    terserOptions: {
      compress: {
        drop_console: true, // 生产环境去掉控制台 console
        drop_debugger: true, // 生产环境去掉控制台 debugger 默认就是true
        dead_code: true, // 删除无法访问的代码 默认就是true
      },
    },
    rollupOptions: {
      input: {
        main: resolve(__dirname, "index.html"),
        // nested: resolve(__dirname, 'nested/index.html'), // 多页面选项
      },
      output: {
        // 1. 对象配置
        // manualChunks: {
        //   // 'react-vendor': ['react', 'react-dom'], // 将 React 相关库打包成单独的 chunk 中 如果CDN有了，这里就不需要引入
        //   // lodash: ['lodash-es'], // 将 Lodash 库的代码单独打包
        //   // library: ["antd"], // 将组件库的代码打包
        // },
        // 最小化拆分包
        manualChunks(id) {
          if (id.includes("node_modules")) {
            return id.toString().split("node_modules/")[1].split("/")[0].toString();
          }
        },
        // dist下面的assets文件下，里面既有js、css等等。因此，可以将不同的文件放在不同的文件下，这样比较好。
        // 拆分js到模块文件夹
        chunkFileNames: (chunkInfo) => {
          const facadeModuleId = chunkInfo.facadeModuleId
            ? chunkInfo.facadeModuleId.split("/")
            : [];
          const fileName1 = facadeModuleId[facadeModuleId.length - 2] || "[name]";
          return `js/${fileName1}/[name].[hash].${buildTime}.js`;
        },
        // 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]表示该文件内容hash值
        entryFileNames: `js/[name].[hash].${buildTime}.js`,
        // 用于输出静态资源的命名，[ext]表示文件扩展名
        assetFileNames: `[ext]/[name].[hash:4].${buildTime}.[ext]`,
      },
      // external: ['react', 'react-dom'], // 确保外部化处理那些你不想打包进库的依赖
    },
  },
});
